package com.zpark.it.service.impl;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zpark.it.clients.ProductClient;
import com.zpark.it.doc.ProductDoc;
import com.zpark.it.param.ProductIdsParam;
import com.zpark.it.param.ProductSearchParam;
import com.zpark.it.pojo.Product;
import com.zpark.it.service.SearchService;
import com.zpark.it.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Title: SearchServiceImpl
 * @Author Charles
 * @Package com.zpark.it.service.impl
 * @Date 2023/7/23 16:47
 */
@Service
@Slf4j
public class SearchServiceImpl implements SearchService {
    /**
     * 根据关键字和分页进行数据库数据查询
     * 1、判断关键字是否为空，如果为null查询全部，不为空  all字段查询
     * 2、添加分页属性
     * 3、es查询
     * 4、结果处理
     * @param productSearchParam
     * @return
     */
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public R search(ProductSearchParam productSearchParam) {

        SearchRequest searchRequest=new SearchRequest("product");

        String search = productSearchParam.getSearch();

        if (StringUtils.isEmpty(search)){
            //null
            searchRequest.source().query(QueryBuilders.matchAllQuery());//查询全部数据
        }else {
            //不为空
            //添加all的匹配
            searchRequest.source().query(QueryBuilders.matchQuery("all",search));
        }
        //进行分页数据添加
        searchRequest.source().from((productSearchParam.getCurrentPage()-1)*productSearchParam.getPageSize());  // 偏移量（当前页数-1）*页容量
        searchRequest.source().size(productSearchParam.getPageSize());

        SearchResponse searchResponse=null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询错误");
        }

        SearchHits hits = searchResponse.getHits();
        //查询符合的数量
        long total = hits.getTotalHits().value;
        //拿到数据集合
        SearchHit[] hitsHits = hits.getHits();

        List<Product> productList=new ArrayList<>();
        //json处理器
        ObjectMapper objectMapper=new ObjectMapper();

        for (SearchHit hitsHit : hitsHits) {
            //拿到productDoc模型对应的json数据
            String sourceAsString = hitsHit.getSourceAsString();
            //
            Product product = null;
            try {
                //productDoc all 转为product对象，如果product对象没有all的属性，转不成json
                //TODO：修改product的实体类，添加忽略没有属性的注解！
                product = objectMapper.readValue(sourceAsString, Product.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            productList.add(product);
        }

        R r = R.ok(null, productList, total);
        log.info("业务结束：{}",r);
        return r;
    }

    /**
     * 商品同步调用
     *
     * @param product
     * @return
     */
    @Override
    public R save(Product product) throws IOException {
        IndexRequest indexRequest=new IndexRequest("product").id(product.getProductId().toString());

        ProductDoc productDoc=new ProductDoc(product);

        ObjectMapper objectMapper=new ObjectMapper();
        String json=objectMapper.writeValueAsString(productDoc);

        indexRequest.source(json, XContentType.JSON);

        restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        return R.ok("数据同步成功");
    }

    /**
     * es库的商品删除
     *
     * @param productId
     * @return
     */
    @Override
    public R remove(Integer productId) throws IOException {
        DeleteRequest request=new DeleteRequest("product").id(productId.toString());
        restHighLevelClient.delete(request,RequestOptions.DEFAULT);
        return R.ok("数据删除成功");
    }

}
